package com.songlanyun.modules.userbankcard.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.enums.MemberConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.BeanUtil;
import com.songlanyun.modules.account.entity.UserInfoEntity;
import com.songlanyun.modules.exception.MemberException;
import com.songlanyun.modules.userbankcard.model.dto.UserBankCardDTO;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.userbankcard.dao.UserBankCardDao;
import com.songlanyun.modules.userbankcard.entity.UserBankCardEntity;
import com.songlanyun.modules.userbankcard.service.UserBankCardService;
import reactor.core.publisher.Mono;


@Service("userBankCardService")
public class UserBankCardServiceImpl extends ServiceImpl<UserBankCardDao, UserBankCardEntity> implements UserBankCardService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Integer userType = MapUtil.getInt(params, "user_type");
        Long identityId = MapUtil.getLong(params, "identityId");

        IPage<UserBankCardEntity> page = this.page(
                new Query<UserBankCardEntity>().getPage(params),
                new LambdaQueryWrapper<UserBankCardEntity>()
                        .eq(UserBankCardEntity::getUserType, userType)
                        .eq(UserBankCardEntity::getIdentityId, identityId)
                        .orderByDesc(UserBankCardEntity::getIsDefault)
                        .orderByDesc(UserBankCardEntity::getCreateTime)
        );

        return new PageUtils(page);
    }

    @Override
    public UserBankCardEntity getById(Long id, boolean isThrow) {
        UserBankCardEntity userBankCardEntity = this.baseMapper.selectById(id);
        if (userBankCardEntity == null) {
            if (isThrow) {
                throw new RRException(MemberException.USER_BANK_CARD_NOT_EXISTS);
            }
        }

        return userBankCardEntity;
    }

    @Override
    public List<UserBankCardEntity> bankCardList(MemberConstant.UserType userType, Long identityId) {

        return this.baseMapper.selectList(
                new LambdaQueryWrapper<UserBankCardEntity>()
                        .eq(UserBankCardEntity::getUserType, userType)
                        .eq(UserBankCardEntity::getIdentityId, identityId)
                        .orderByDesc(UserBankCardEntity::getIsDefault)
                        .orderByDesc(UserBankCardEntity::getCreateTime)
        );

    }

    /**
     * 用户默认银行卡
     *
     * @param userType
     * @param identityId
     * @return
     */
    @Override
    public UserBankCardEntity defaultBankCard(MemberConstant.UserType userType, Long identityId) {
        return this.baseMapper.selectOne(
                new LambdaQueryWrapper<UserBankCardEntity>()
                        .eq(UserBankCardEntity::getUserType, userType)
                        .eq(UserBankCardEntity::getIdentityId, identityId)
                        .eq(UserBankCardEntity::getIsDefault, true)
                        .orderByDesc(UserBankCardEntity::getCreateTime)
                        .last("limit 1")
        );
    }

    @Override
    public void saveBankCard(UserBankCardDTO dto, MemberConstant.UserType userType, Long identityId) {
        UserBankCardEntity bankCard = new UserBankCardEntity();
        //如果该用户是第一次保存，则设为默认银行卡
        isOneDefault(bankCard, userType, identityId);

        if (dto.getId() != null) {
            //修改
            bankCard = this.getById(dto.getId(), true);
        }
        BeanUtil.copyPropertiesIgnoreNull(dto, bankCard);
        bankCard.setUserType(userType);
        bankCard.setIdentityId(identityId);

        this.saveOrUpdate(bankCard);
    }

    /**
     * 用户第一次保存银行卡,则设为默认银行卡
     *
     * @param bankCard
     * @param userType
     * @param identityId
     */
    private void isOneDefault(UserBankCardEntity bankCard, MemberConstant.UserType userType, Long identityId) {
        int count = this.count(
                new LambdaQueryWrapper<UserBankCardEntity>()
                        .eq(UserBankCardEntity::getUserType, userType)
                        .eq(UserBankCardEntity::getIdentityId, identityId)
        );
        //用户第一次保存银行卡,则设为默认银行卡
        if (count <= 0) {
            bankCard.setIsDefault(true);
        }
    }

    @Override
    public void setDefaultBankCard(MemberConstant.UserType userType, Long identityId, Long id) {
        this.getById(id, true);

        List<UserBankCardEntity> list = this.bankCardList(userType, identityId);

        //一个用户只有一个银行卡为默认
        list.forEach(u -> {
            if (u.getId().equals(id)) {
                u.setIsDefault(true);
            } else {
                u.setIsDefault(false);
            }
        });

        this.saveOrUpdateBatch(list);
    }

    @Override
    public PageUtils shopBankCardList(Map<String, Object> params) {
        Long shopId = MapUtil.getLong(params, "shop_id");

        IPage<UserBankCardEntity> page = this.page(
                new Query<UserBankCardEntity>().getPage(params),
                new LambdaQueryWrapper<UserBankCardEntity>()
                        .eq(UserBankCardEntity::getUserType, MemberConstant.UserType.SHOP)
                        .eq(UserBankCardEntity::getIdentityId, shopId)
                        .orderByDesc(UserBankCardEntity::getCreateTime)
        );

        return new PageUtils(page);
    }

    @Override
    public List<UserBankCardEntity> shopBankCards(Map<String, Object> params) {
        Long shopId = MapUtil.getLong(params, "shop_id");

        return this.baseMapper.selectList(
                new LambdaQueryWrapper<UserBankCardEntity>()
                        .eq(UserBankCardEntity::getUserType, MemberConstant.UserType.SHOP)
                        .eq(UserBankCardEntity::getIdentityId, shopId)
                        .orderByDesc(UserBankCardEntity::getCreateTime)
        );
    }

    @Override
    public UserBankCardEntity loadById(Long userId, Long userBankId, boolean tw) {
        UserBankCardEntity userBankCardEntity = this.lambdaQuery()
                .eq(UserBankCardEntity::getId, userBankId)
                .eq(UserBankCardEntity::getUserType, MemberConstant.UserType.MEMBER)
                .eq(UserBankCardEntity::getIdentityId, userId)
                .last("limit 1")
                .one();
        if (ObjectUtil.isNull(userBankCardEntity) && tw) {
            throw new RRException(MemberException.USER_BANK_CARD_NOT_EXISTS);
        }

        return userBankCardEntity;
    }

}
